/*
 * Copyright 2007 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.jtell;

import org.jtell.config.EventSinkMetadata;

/**
 * <p>
 * <code>EventSink</code> defines the public interface to an event sink. An event sink is an object through which an
 * event may be routed to an application listener object. It also provides access to a {@link EventSinkMetadata}
 * instance which describes certain properties of the event sink, such as information on the types of events for which
 * it must be notified.
 * </p>
 * <p>
 * Implementors of this interface must implement {@link #equals(Object)} and {@link #hashCode()} such that two instances
 * which refer to equal owner and metadata objects are themselves considered equal. 
 * </p>
 */
public interface EventSink
{
    /**
     * <p>
     * Get the event sink metadata. 
     * </p>
     *
     * @return {@link EventSinkMetadata} instance.
     */
    EventSinkMetadata getEventSinkMetadata();

    /**
     * <p>
     * Get the object which owns the event sink. This will typically be the application listener object which exports
     * the event sink; for example, the instance upon which an event sink method will be invoked.
     * </p>
     *
     * @return {@link Object} owner object or <code>null</code> if the instance is invalid.
     */
    Object getOwner();

    /**
     * <p>
     * Get a string uniquely identifying the target of this event sink. For example, if the event sink targets a method
     * on an application listener object, the returned string could be the fully qualified declaring class name followed
     * by the method signature. This allows event sinks with identical targets to be identified so we can suppress
     * multiple invocations for a single event.
     * </p>
     *
     * @return {@link String} target identifier.
     */
    String getTargetId();

    /**
     * <p>
     * Determine whether the event sink is still valid. An event sink may become invalid if, for example, the reference
     * to its owner object is held weakly and application code no longer holds any references to it.
     * </p>
     *
     * @return <code>boolean</code> <code>true</code> if the instance is still valid.
     */
    boolean isValid();

    /**
     * <p>
     * Notify the listener of an event.
     * </p>
     * 
     * @param event the event object.
     * @throws EventSinkException if an error occurs while the listener is handling the event.
     */
    void notifyListener(Object event) throws EventSinkException;
}
